package impl;

import java.util.Date;

import java.util.List;

import api.IAuthenticator;
import api.IFacade;
import api.ILotteryProxy;
import api.ISocializer;
import api.IUserDataManager;
import api.IWallet;
import api.InvalidAuthenticationException;

import javax.ejb.EJB;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import entities.Friend;
import entities.Lindenmovement;
import entities.LotteryGame;
import entities.Usermessage;
import entities.Userprofile;

/**
 * Session Bean implementation class Facade
 */
@Stateful(name = "IFacade")
public class Facade implements IFacade {
	@PersistenceContext(unitName = "PhaseBookPU")
	EntityManager em;

	@EJB(beanName = "IAuthenticator")
	IAuthenticator authenticator;
	@EJB(beanName = "ILotteryProxy")
	ILotteryProxy lotteryProxy;
	@EJB(beanName = "ISocializer")
	ISocializer socializer;
	@EJB(beanName = "IUserDataManager")
	IUserDataManager dataManager;
	@EJB(beanName = "IWallet")
	IWallet wallet;

	int uid_;
	boolean authenticated;

	/**
	 * Default constructor.
	 */
	public Facade() {
		authenticated = false;
	}

	private void validateAuthentication() throws InvalidAuthenticationException {

		if (!authenticated) {
			System.out.println("*** Validation required ***");
			throw new InvalidAuthenticationException();
		}

	}

	@Override
	public boolean registerUser(String username, String password)
			throws InvalidAuthenticationException {

		try {

			return this.authenticator.registerUser(username, password);

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public boolean authenticate(String username, String password)
			throws InvalidAuthenticationException {

		try {

			if (this.authenticator.authenticate(username, password)) {

				this.authenticated = true;
				Userprofile profile = this.getProfileByUsername(username);
				this.uid_ = profile.getUserId();

				return true;
			}

		} catch (Exception e) {
			e.printStackTrace();
			throw new InvalidAuthenticationException();
		}
		return false;
	}

	@Override
	public Date getLastLogin(String username)
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {

			return this.authenticator.getLastLogin(username);
		} catch (Exception e) {
			return null;
		}

	}

	@Override
	public boolean resetPassword(String username)
			throws InvalidAuthenticationException {

		try {
			return this.authenticator.resetPassword(username);

		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean registerBet(int uid, int choice, int amount, int gameId)
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {

			return this.lotteryProxy.registerBet(uid, choice, amount, gameId);

		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public LotteryGame getActiveLotteryDetails()
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {
			return this.lotteryProxy.getActiveLotteryDetails();

		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public List<String> searchFriends(String searchString)
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {
			return this.socializer.searchFriends(searchString);

		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public boolean sendFriendshipInvitation(int fromId, int toId)
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {
			return this.socializer.sendFriendshipInvitation(fromId, toId);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public List<Friend> getPendingFriendshipRequests(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();

		try {
			return this.socializer.getPendingFriendshipRequests(uid);
		} catch (Exception e) {
			return null;
		}

	}

	@Override
	public boolean confirmFriendshipRequest(int uid, int requesterdId)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.confirmFriendshipRequest(uid, requesterdId);
		} catch (Exception e) {
			return false;
		}

	}

	@Override
	public boolean isFriendWith(int baseId, int friendId)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.isFriendWith(baseId, friendId);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public List<Userprofile> getMyFriends(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.getMyFriends(uid);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public boolean publishPublicMessage(int ownerId, int posterId,
			String message, int photoId) throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.publishPublicMessage(ownerId, posterId,
					message, photoId);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean publishPrivateMessage(int ownerId, int posterId,
			String message, int photoId) throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.publishPrivateMessage(ownerId, posterId,
					message, photoId);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public List<Usermessage> getPublicMessageList(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.getPublicMessageList(uid);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public int addPhoto(int uid, String photoPath)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.addPhoto(uid, photoPath);
		} catch (Exception e) {
			return -1;
		}
	}

	@Override
	public List<Usermessage> getPrivateMessageList(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.socializer.getPrivateMessageList(uid);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public boolean updateName(int uid, String name)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateName(uid, name);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updateAge(int uid, int age)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateAge(uid, age);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updateCity(int uid, String city)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateCity(uid, city);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updateGender(int uid, Gender sex)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateGender(uid, sex);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updateEmail(int uid, String email)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateEmail(uid, email);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updateNotificationApproach(int uid,
			NotificationApproach approach, boolean flag)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updateNotificationApproach(uid, approach,
					flag);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean updatePhoto(int uid, int photoId)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.updatePhoto(uid, photoId);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public Userprofile getProfileById(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.getProfileById(uid);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public Userprofile getProfileByUsername(String username)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.dataManager.getProfileByUsername(username);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public boolean reloadLinden(int uid, int amount)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.wallet.reloadLinden(uid, amount);
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public List<Lindenmovement> getMovements(int uid)
			throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.wallet.getMovements(uid);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public Userprofile getLoggedProfile() throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.getProfileById(uid_);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public Integer getLoggedUserId() throws InvalidAuthenticationException {
		validateAuthentication();
		try {
			return this.uid_;
		} catch (Exception e) {
			return -1;
		}
	}

}
